
<template>
  <div class="excel-container">
    <div class="toolbar">
      <el-button-group>
        <el-button @click="mergeCells" :disabled="!canMerge" size="small">
          合并单元格
        </el-button>
        <el-button @click="unmergeCells" :disabled="!canUnmerge" size="small">
          取消合并
        </el-button>
      </el-button-group>

      <el-select
        v-model="currentStyle.fontSize"
        size="small"        style="width: 100px; margin-left: 10px;"
        @change="applyStyle('fontSize', $event)"
      >
        <el-option
          v-for="size in [10, 12, 14, 16, 18, 20, 24]"
          :key="size"
          :label="size + 'px'"
          :value="size"
        />
      </el-select>

      <el-color-picker
        v-model="currentStyle.color"
        size="small"
        @change="applyStyle('color', $event)"        style="margin-left: 10px;"
      />

      <el-button-group style="margin-left: 10px;">
        <el-button
          @click="applyStyle('fontWeight', currentStyle.fontWeight === 'bold' ? 'normal' : 'bold')"
          :type="currentStyle.fontWeight === 'bold' ? 'primary' : 'default'"
          size="small"
        >
          B
        </el-button>

        <el-button
          @click="applyStyle('fontStyle', currentStyle.fontStyle === 'italic' ? 'normal' : 'italic')"
          :type="currentStyle.fontStyle === 'italic' ? 'primary' : 'default'"
          size="small"
        >
          I
        </el-button>
      </el-button-group>

      <el-button-group style="margin-left: 10px;">
        <el-button
          @click="applyStyle('textAlign', 'left')"
          :type="currentStyle.textAlign === 'left' ? 'primary' : 'default'"
          size="small"
        >
          <el-icon><Promotion /></el-icon>
        </el-button>

        <el-button
          @click="applyStyle('textAlign', 'center')"
          :type="currentStyle.textAlign === 'center' ? 'primary' : 'default'"
          size="small"
        >
          <el-icon><CopyDocument /></el-icon>
        </el-button>

        <el-button
          @click="applyStyle('textAlign', 'right')"
          :type="currentStyle.textAlign === 'right' ? 'primary' : 'default'"
          size="small"
        >
          <el-icon><Download /></el-icon>
        </el-button>
      </el-button-group>

      <el-color-picker
        v-model="currentStyle.backgroundColor"
        size="small"
        @change="applyStyle('backgroundColor', $event)"        style="margin-left: 10px;"
      />
    </div>

    <div class="excel-wrapper" ref="excelWrapper">
      <table class="excel-table">
        <thead>
        <tr>
          <th class="corner"></th>
          <th
            v-for="col in columns"
            :key="col"
            class="col-header"
            :style="{ width: columnWidths[col] + 'px' }"
            @dblclick="autoResizeColumn(col)"
          >
            {{ col }}
            <div
              class="col-resizer"
              @mousedown="startColumnResize(col, $event)"
            ></div>
          </th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="row in rows" :key="row">
          <td class="row-header" @dblclick="autoResizeRow(row)">
            {{ row }}
            <div
              class="row-resizer"
              @mousedown="startRowResize(row, $event)"
            ></div>
          </td>
          <td
            v-for="col in columns"
            :key="col + row"
            :ref="setCellRef(col, row)"
            class="excel-cell"
            :class="{
                selected: isSelected(col, row),
                'range-selected': isRangeSelected(col, row),
                merged: isMerged(col, row),
                'merge-main': isMergeMain(col, row)
              }"
            :rowspan="getCellRowSpan(col, row)"
            :colspan="getCellColSpan(col, row)"
            :style="getCellStyles(col, row)"
            @click="selectCell(col, row, $event)"
            @dblclick="editCell(col, row)"
            @mousedown="startRangeSelect(col, row, $event)"
          >
            <div
              v-if="!isEditingCell(col, row)"
              class="cell-content"
              v-html="getCellDisplayText(col, row)"
            ></div>
            <textarea
              v-else
              v-model="editingCell.content"
              class="cell-editor"
              :ref="(el) => { if (el && isEditingCell(col, row)) editorRef = el }"
              @blur="finishEditing"
              @keydown="handleEditorKeydown"
            ></textarea>
          </td>
        </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script setup lang="ts">import { ref, reactive, computed, nextTick, onMounted } from 'vue'
import { Promotion, CopyDocument, Download } from '@element-plus/icons-vue'

// 类型定义
interface Cell {
  text: string
  style: {
    fontSize: number
    color: string
    fontWeight: string
    fontStyle: string
    backgroundColor: string
    textAlign: string
  }
  merge: {
    isMain: boolean // 是否为合并区域的主单元格
    rowSpan: number
    colSpan: number
    masterCell: string | null // 如果是合并的子单元格，指向主单元格坐标
  }
}

// 响应式数据
const rows = ref<number[]>([])
const columns = ref<string[]>([])
const cells = ref<Record<string, Cell>>({})
const selectedCells = ref<{ start: { col: string; row: number }; end: { col: string; row: number } } | null>(null)
const editingCell = ref<{ col: string; row: number; content: string } | null>(null)
const editorRef = ref<HTMLTextAreaElement | null>(null)
const currentStyle = reactive({
  fontSize: 14,
  color: '#000000',
  fontWeight: 'normal',
  fontStyle: 'normal',
  backgroundColor: '#ffffff',
  textAlign: 'left'
})

// 尺寸相关
const columnWidths = ref<Record<string, number>>({})
const rowHeights = ref<Record<number, number>>({})
const resizing = ref<{ type: 'column' | 'row'; key: string | number; startX: number; startY: number; startSize: number } | null>(null)
const rangeSelecting = ref(false)

// 初始化
const init = () => {
  // 创建列 A-N
  for (let i = 0; i < 14; i++) {
    const col = String.fromCharCode(65 + i)
    columns.value.push(col)
    columnWidths.value[col] = 100
  }

  // 创建行 1-20
  for (let i = 1; i <= 20; i++) {
    rows.value.push(i)
    rowHeights.value[i] = 30
  }

  // 初始化单元格
  for (const row of rows.value) {
    for (const col of columns.value) {
      const key = `${col}${row}`
      cells.value[key] = {
        text: '',
        style: {
          fontSize: 14,
          color: '#000000',
          fontWeight: 'normal',
          fontStyle: 'normal',
          backgroundColor: '#ffffff',
          textAlign: 'left'
        },
        merge: {
          isMain: false,
          rowSpan: 1,
          colSpan: 1,
          masterCell: null
        }
      }
    }
  }
}

// 设置单元格引用
const cellRefs = ref<Record<string, HTMLElement>>({})
const setCellRef = (col: string, row: number) => (el: HTMLElement | null) => {
  const key = `${col}${row}`
  if (el) {
    cellRefs.value[key] = el
    el.dataset.cell = key // 用于识别单元格
  }
}

// 单元格选择
const selectCell = (col: string, row: number, event: MouseEvent) => {
  if (event.shiftKey && selectedCells.value) {
    // 范围选择
    selectedCells.value.end = { col, row }
  } else {
    // 单个单元格选择
    selectedCells.value = {
      start: { col, row },
      end: { col, row }
    }
  }
  updateCurrentStyle()
}

// 开始范围选择
const startRangeSelect = (col: string, row: number, event: MouseEvent) => {
  if (event.button !== 0) return // 只处理左键

  // 设置起始点
  if (!event.shiftKey) {
    selectedCells.value = {
      start: { col, row },
      end: { col, row }
    }
  }

  rangeSelecting.value = true

  const handleMouseMove = (moveEvent: MouseEvent) => {
    if (!rangeSelecting.value) return

    const target = moveEvent.target as HTMLElement
    const cell = target.closest('.excel-cell')

    if (cell && cell.dataset.cell) {
      const cellKey = cell.dataset.cell
      const match = cellKey.match(/([A-Z]+)(\d+)/)
      if (match) {
        const [, cellCol, cellRowStr] = match
        const cellRow = parseInt(cellRowStr)

        if (selectedCells.value) {
          selectedCells.value.end = { col: cellCol, row: cellRow }
        }
      }
    }
  }

  const handleMouseUp = () => {
    rangeSelecting.value = false
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
  }

  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)

  // 防止文本选择
  event.preventDefault()
}

// 检查是否选中
const isSelected = (col: string, row: number) => {
  if (!selectedCells.value) return false
  const { start } = selectedCells.value
  return start.col === col && start.row === row
}

// 检查是否在选中范围内
const isRangeSelected = (col: string, row: number) => {
  if (!selectedCells.value) return false

  const { start, end } = selectedCells.value
  const startColIndex = columns.value.indexOf(start.col)
  const endColIndex = columns.value.indexOf(end.col)
  const startRowIndex = start.row
  const endRowIndex = end.row

  const minColIndex = Math.min(startColIndex, endColIndex)
  const maxColIndex = Math.max(startColIndex, endColIndex)
  const minRowIndex = Math.min(startRowIndex, endRowIndex)
  const maxRowIndex = Math.max(startRowIndex, endRowIndex)

  const currentColIndex = columns.value.indexOf(col)
  const currentRowIndex = row

  return (
    currentColIndex >= minColIndex &&
    currentColIndex <= maxColIndex &&
    currentRowIndex >= minRowIndex &&
    currentRowIndex <= maxRowIndex
  )
}

// 获取选中的所有单元格
const getSelectedCellKeys = () => {
  if (!selectedCells.value) return []

  const { start, end } = selectedCells.value
  const startColIndex = columns.value.indexOf(start.col)
  const endColIndex = columns.value.indexOf(end.col)
  const startRowIndex = start.row
  const endRowIndex = end.row

  const minColIndex = Math.min(startColIndex, endColIndex)
  const maxColIndex = Math.max(startColIndex, endColIndex)
  const minRowIndex = Math.min(startRowIndex, endRowIndex)
  const maxRowIndex = Math.max(startRowIndex, endRowIndex)

  const keys: string[] = []
  for (let r = minRowIndex; r <= maxRowIndex; r++) {
    for (let cIndex = minColIndex; cIndex <= maxColIndex; cIndex++) {
      const col = columns.value[cIndex]
      const key = `${col}${r}`

      // 只添加主单元格（非合并子单元格）
      const cell = cells.value[key]
      if (cell && !cell.merge.masterCell) {
        keys.push(key)
      }
    }
  }

  return keys
}

// 合并单元格相关计算属性
const canMerge = computed(() => {
  if (!selectedCells.value) return false

  const { start, end } = selectedCells.value
  return start.col !== end.col || start.row !== end.row
})

const canUnmerge = computed(() => {
  if (!selectedCells.value) return false

  const { start } = selectedCells.value
  const cell = cells.value[`${start.col}${start.row}`]
  return cell && cell.merge.isMain
})

// 合并单元格
const mergeCells = () => {
  if (!canMerge.value || !selectedCells.value) return

  const { start, end } = selectedCells.value
  const startColIndex = columns.value.indexOf(start.col)
  const endColIndex = columns.value.indexOf(end.col)
  const startRowIndex = start.row
  const endRowIndex = end.row

  const minColIndex = Math.min(startColIndex, endColIndex)
  const maxColIndex = Math.max(startColIndex, endColIndex)
  const minRowIndex = Math.min(startRowIndex, endRowIndex)
  const maxRowIndex = Math.max(startRowIndex, endRowIndex)

  // 主单元格
  const mainCol = columns.value[minColIndex]
  const mainRow = minRowIndex
  const mainKey = `${mainCol}${mainRow}`

  const mainCell = cells.value[mainKey]
  if (!mainCell) return

  // 设置主单元格为合并状态
  mainCell.merge.isMain = true
  mainCell.merge.rowSpan = maxRowIndex - minRowIndex + 1
  mainCell.merge.colSpan = maxColIndex - minColIndex + 1

  // 标记其他单元格为子单元格
  for (let r = minRowIndex; r <= maxRowIndex; r++) {
    for (let cIndex = minColIndex; cIndex <= maxColIndex; cIndex++) {
      const col = columns.value[cIndex]
      const key = `${col}${r}`

      if (col === mainCol && r === mainRow) continue // 跳过主单元格

      const cell = cells.value[key]
      if (cell) {
        cell.merge.masterCell = mainKey
        cell.text = ''
      }
    }
  }

  // 选中主单元格
  selectedCells.value = {
    start: { col: mainCol, row: mainRow },
    end: { col: mainCol, row: mainRow }
  }
}

// 取消合并
const unmergeCells = () => {
  if (!canUnmerge.value || !selectedCells.value) return

  const { start } = selectedCells.value
  const key = `${start.col}${start.row}`
  const cell = cells.value[key]

  if (!cell || !cell.merge.isMain) return

  const { rowSpan, colSpan } = cell.merge
  const startColIndex = columns.value.indexOf(start.col)
  const startRowIndex = start.row

  // 重置主单元格
  cell.merge.isMain = false
  cell.merge.rowSpan = 1
  cell.merge.colSpan = 1

  // 重置子单元格
  for (let r = startRowIndex; r < startRowIndex + rowSpan; r++) {
    for (let cIndex = startColIndex; cIndex < startColIndex + colSpan; cIndex++) {
      if (cIndex >= columns.value.length) break

      const col = columns.value[cIndex]
      const childKey = `${col}${r}`

      if (col === start.col && r === start.row) continue // 跳过主单元格

      const childCell = cells.value[childKey]
      if (childCell) {
        childCell.merge.masterCell = null
      }
    }
  }
}

// 检查是否为合并单元格
const isMerged = (col: string, row: number) => {
  const key = `${col}${row}`
  const cell = cells.value[key]
  return cell && !!cell.merge.masterCell
}

// 检查是否为合并主单元格
const isMergeMain = (col: string, row: number) => {
  const key = `${col}${row}`
  const cell = cells.value[key]
  return cell && cell.merge.isMain
}

// 获取单元格行跨度
const getCellRowSpan = (col: string, row: number) => {
  const key = `${col}${row}`
  const cell = cells.value[key]

  if (!cell) return 1

  if (cell.merge.masterCell) return 0 // 子单元格不显示

  return cell.merge.rowSpan
}

// 获取单元格列跨度
const getCellColSpan = (col: string, row: number) => {
  const key = `${col}${row}`
  const cell = cells.value[key]

  if (!cell) return 1

  if (cell.merge.masterCell) return 0 // 子单元格不显示

  return cell.merge.colSpan
}

// 获取单元格显示文本
const getCellDisplayText = (col: string, row: number) => {
  const key = `${col}${row}`
  const cell = cells.value[key]

  if (!cell) return ''

  // 如果是合并的子单元格，不显示内容
  if (cell.merge.masterCell) return ''

  return cell.text
}

// 获取单元格样式
const getCellStyles = (col: string, row: number) => {
  const key = `${col}${row}`
  let cell = cells.value[key]

  // 如果是合并的子单元格，使用主单元格的样式
  if (cell && cell.merge.masterCell) {
    cell = cells.value[cell.merge.masterCell]
  }

  if (!cell) return {}

  return {
    fontSize: cell.style.fontSize + 'px',
    color: cell.style.color,
    fontWeight: cell.style.fontWeight,
    fontStyle: cell.style.fontStyle,
    backgroundColor: cell.style.backgroundColor,
    textAlign: cell.style.textAlign,
    width: columnWidths.value[col] + 'px',
    height: rowHeights.value[row] + 'px'
  }
}

// 编辑单元格
const editCell = (col: string, row: number) => {
  const key = `${col}${row}`
  let cell = cells.value[key]

  // 如果是合并的子单元格，编辑主单元格
  if (cell && cell.merge.masterCell) {
    cell = cells.value[cell.merge.masterCell]
  }

  if (!cell) return

  editingCell.value = {
    col,
    row,
    content: cell.text
  }

  nextTick(() => {
    // 修复：使用正确的单元格引用获取编辑器元素
    if (editorRef.value) {
      editorRef.value.focus()
      editorRef.value.select()
    }
  })
}

// 完成编辑
const finishEditing = () => {
  if (!editingCell.value) return

  const { col, row, content } = editingCell.value
  const key = `${col}${row}`
  let cell = cells.value[key]

  // 如果是合并的子单元格，更新主单元格
  if (cell && cell.merge.masterCell) {
    cell = cells.value[cell.merge.masterCell]
  }

  if (cell) {
    cell.text = content
  }

  editingCell.value = null
  editorRef.value = null // 清除编辑器引用
}

// 处理编辑器按键
const handleEditorKeydown = (event: KeyboardEvent) => {
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    finishEditing()
  } else if (event.key === 'Escape') {
    editingCell.value = null
    editorRef.value = null
  }
}

// 是否正在编辑指定单元格
const isEditingCell = (col: string, row: number) => {
  return editingCell.value?.col === col && editingCell.value?.row === row
}

// 应用样式
const applyStyle = (property: string, value: any) => {
  const selectedKeys = getSelectedCellKeys()

  for (const key of selectedKeys) {
    const cell = cells.value[key]
    if (cell) {
      cell.style[property] = value
    }
  }

  // 更新当前样式
  currentStyle[property] = value
}

// 更新当前样式显示
const updateCurrentStyle = () => {
  const selectedKeys = getSelectedCellKeys()
  if (selectedKeys.length === 0) return

  const firstCell = cells.value[selectedKeys[0]]
  if (!firstCell) return

  currentStyle.fontSize = firstCell.style.fontSize
  currentStyle.color = firstCell.style.color
  currentStyle.fontWeight = firstCell.style.fontWeight
  currentStyle.fontStyle = firstCell.style.fontStyle
  currentStyle.backgroundColor = firstCell.style.backgroundColor
  currentStyle.textAlign = firstCell.style.textAlign
}

// 列宽调整
const startColumnResize = (col: string, event: MouseEvent) => {
  event.preventDefault()
  event.stopPropagation()

  const startX = event.clientX
  const startWidth = columnWidths.value[col]

  const handleMouseMove = (moveEvent: MouseEvent) => {
    const diff = moveEvent.clientX - startX
    columnWidths.value[col] = Math.max(30, startWidth + diff)
  }

  const handleMouseUp = () => {
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
  }

  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

// 行高调整
const startRowResize = (row: number, event: MouseEvent) => {
  event.preventDefault()
  event.stopPropagation()

  const startY = event.clientY
  const startHeight = rowHeights.value[row]

  const handleMouseMove = (moveEvent: MouseEvent) => {
    const diff = moveEvent.clientY - startY
    rowHeights.value[row] = Math.max(20, startHeight + diff)
  }

  const handleMouseUp = () => {
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
  }

  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

// 自动调整列宽
const autoResizeColumn = (col: string) => {
  let maxWidth = 50

  for (const row of rows.value) {
    const key = `${col}${row}`
    const cell = cells.value[key]

    if (cell && !cell.merge.masterCell) {
      // 简单估算内容宽度
      const contentLength = cell.text.length
      const estimatedWidth = Math.min(300, Math.max(50, contentLength * 8))
      maxWidth = Math.max(maxWidth, estimatedWidth)
    }
  }

  columnWidths.value[col] = maxWidth
}

// 自动调整行高
const autoResizeRow = (row: number) => {
  let maxHeight = 30

  for (const col of columns.value) {
    const key = `${col}${row}`
    const cell = cells.value[key]

    if (cell && !cell.merge.masterCell) {
      // 简单估算内容高度
      const lineCount = Math.max(1, Math.ceil(cell.text.length / 20))
      const estimatedHeight = Math.min(200, Math.max(30, lineCount * 20))
      maxHeight = Math.max(maxHeight, estimatedHeight)
    }
  }

  rowHeights.value[row] = maxHeight
}

// 初始化
onMounted(() => {
  init()
})
</script>

<style scoped>.excel-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 10px;
  box-sizing: border-box;
}

.toolbar {
  display: flex;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid #e0e0e0;
  margin-bottom: 10px;
  flex-wrap: wrap;
  gap: 5px;
}

.excel-wrapper {
  flex: 1;
  overflow: auto;
  border: 1px solid #d0d0d0;
}

.excel-table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}

.excel-table th,
.excel-table td {
  border: 1px solid #d0d0d0;
  position: relative;
  overflow: hidden;
}

.corner {
  width: 50px;
  height: 30px;
  background-color: #f5f5f5;
  text-align: center;
  line-height: 30px;
}

.col-header {
  height: 30px;
  background-color: #f8f8f8;
  text-align: center;
  line-height: 30px;
  user-select: none;
  position: relative;
}

.col-resizer {
  position: absolute;
  right: 0;
  top: 0;
  width: 5px;
  height: 100%;
  cursor: col-resize;
  background-color: transparent;
}

.col-resizer:hover {
  background-color: #409eff;
}

.row-header {
  width: 50px;
  background-color: #f8f8f8;
  text-align: center;
  line-height: 30px;
  user-select: none;
  position: relative;
}

.row-resizer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 5px;
  cursor: row-resize;
  background-color: transparent;
}

.row-resizer:hover {
  background-color: #409eff;
}

.excel-cell {
  padding: 2px 4px;
  vertical-align: top;
  position: relative;
  cursor: cell;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.excel-cell.selected {
  outline: 2px solid #409eff;
  outline-offset: -2px;
  z-index: 2;
}

.excel-cell.range-selected {
  background-color: rgba(64, 158, 255, 0.1);
}

.excel-cell.merged {
  display: none;
}

.excel-cell.merge-main {
  display: table-cell;
  vertical-align: middle;
}

.cell-editor {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 2px solid #409eff;
  outline: none;
  resize: none;
  padding: 2px 4px;
  box-sizing: border-box;
  background-color: white;
  z-index: 10;
  font-family: inherit;
}
</style>
